package com.ruoyi.ma.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.ma.domain.MaMaterialMeasureQh;
import com.ruoyi.ma.domain.MaMaterialOtherMeasure;
import com.ruoyi.ma.domain.MaMaterialProgressDetails;
import com.ruoyi.ma.domain.vo.MaMaterialProgressDetailsVo;
import com.ruoyi.ma.mapper.MaMaterialMeasureQhMapper;
import com.ruoyi.ma.mapper.MaMaterialProgressDetailsMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.ma.domain.bo.MaMaterialMeasureSingleBo;
import com.ruoyi.ma.domain.vo.MaMaterialMeasureSingleVo;
import com.ruoyi.ma.domain.MaMaterialMeasureSingle;
import com.ruoyi.ma.mapper.MaMaterialMeasureSingleMapper;
import com.ruoyi.ma.service.IMaMaterialMeasureSingleService;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.stream.Collectors;

/**
 * 材料计量单Service业务层处理
 *
 * @author llb
 * @date 2024-11-01
 */
@RequiredArgsConstructor
@Service
public class MaMaterialMeasureSingleServiceImpl implements IMaMaterialMeasureSingleService {

    private final MaMaterialMeasureSingleMapper baseMapper;
    private final MaMaterialProgressDetailsMapper progressDetailsMapper;
    private final MaMaterialMeasureQhMapper qhMapper;

    /**
     * 查询材料计量单
     */
    @Override
    public MaMaterialMeasureSingleVo queryById(Long measureSingleId){
        return baseMapper.selectVoById(measureSingleId);
    }

    /**
     * 查询材料计量单列表
     */
    @Override
    public TableDataInfo<MaMaterialMeasureSingleVo> queryPageList(MaMaterialMeasureSingleBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<MaMaterialMeasureSingle> lqw = buildQueryWrapper(bo);
        Page<MaMaterialMeasureSingleVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询材料计量单列表
     */
    @Override
    public List<MaMaterialMeasureSingleVo> queryList(MaMaterialMeasureSingleBo bo) {
        LambdaQueryWrapper<MaMaterialMeasureSingle> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<MaMaterialMeasureSingle> buildQueryWrapper(MaMaterialMeasureSingleBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<MaMaterialMeasureSingle> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getMeasureQhId() != null, MaMaterialMeasureSingle::getMeasureQhId, bo.getMeasureQhId());
        lqw.eq(bo.getQh() != null, MaMaterialMeasureSingle::getQh, bo.getQh());
        lqw.eq(bo.getBdId() != null, MaMaterialMeasureSingle::getBdId, bo.getBdId());
        lqw.eq(bo.getZdId() != null, MaMaterialMeasureSingle::getZdId, bo.getZdId());
        lqw.eq(bo.getGysId() != null, MaMaterialMeasureSingle::getGysId, bo.getGysId());
        lqw.eq(bo.getType() != null, MaMaterialMeasureSingle::getType, bo.getType());
        lqw.eq(bo.getManifestId() != null, MaMaterialMeasureSingle::getManifestId, bo.getManifestId());
        lqw.eq(StringUtils.isNotBlank(bo.getManifestCode()), MaMaterialMeasureSingle::getManifestCode, bo.getManifestCode());
        lqw.like(StringUtils.isNotBlank(bo.getManifestName()), MaMaterialMeasureSingle::getManifestName, bo.getManifestName());
        lqw.eq(StringUtils.isNotBlank(bo.getModel()), MaMaterialMeasureSingle::getModel, bo.getModel());
        lqw.eq(StringUtils.isNotBlank(bo.getSpecification()), MaMaterialMeasureSingle::getSpecification, bo.getSpecification());
        lqw.eq(StringUtils.isNotBlank(bo.getUnit()), MaMaterialMeasureSingle::getUnit, bo.getUnit());
        lqw.eq(bo.getNumber() != null, MaMaterialMeasureSingle::getNumber, bo.getNumber());
        lqw.eq(bo.getMarketPrice() != null, MaMaterialMeasureSingle::getMarketPrice, bo.getMarketPrice());
        lqw.eq(bo.getAdjustments() != null, MaMaterialMeasureSingle::getAdjustments, bo.getAdjustments());
        lqw.eq(bo.getSettlementPrice() != null, MaMaterialMeasureSingle::getSettlementPrice, bo.getSettlementPrice());
        lqw.eq(bo.getTotal() != null, MaMaterialMeasureSingle::getTotal, bo.getTotal());
        lqw.eq(StringUtils.isNotBlank(bo.getAcceptanceCode()), MaMaterialMeasureSingle::getAcceptanceCode, bo.getAcceptanceCode());
        lqw.eq(bo.getMeNum() != null, MaMaterialMeasureSingle::getMeNum, bo.getMeNum());
        lqw.eq(bo.getMeTotal() != null, MaMaterialMeasureSingle::getMeTotal, bo.getMeTotal());
        lqw.eq(bo.getPreUnmeNum() != null, MaMaterialMeasureSingle::getPreUnmeNum, bo.getPreUnmeNum());
        return lqw;
    }

    /**
     * 新增材料计量单
     */
    @Override
    public Boolean insertByBo(MaMaterialMeasureSingleBo bo) {
        MaMaterialMeasureSingle add = BeanUtil.toBean(bo, MaMaterialMeasureSingle.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setMeasureSingleId(add.getMeasureSingleId());
        }
        return flag;
    }

    /**
     * 修改材料计量单
     */
    @Override
    public Boolean updateByBo(MaMaterialMeasureSingleBo bo) {
        List<MaMaterialMeasureSingle> updateList = bo.getUpdateList();
        updateList.forEach(item -> {
            validEntityBeforeSave(item);
        });
        baseMapper.updateBatchById(updateList);
        return baseMapper.updateBatchById(updateList);
//        MaMaterialMeasureSingle update = BeanUtil.toBean(bo, MaMaterialMeasureSingle.class);
//        validEntityBeforeSave(update);
//        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(MaMaterialMeasureSingle entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除材料计量单
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 获取签收明细
     *
     * @param bo
     * @return
     */
    @Override
    @Transactional
    public List<MaMaterialMeasureSingle> progressDetails(MaMaterialMeasureSingleBo bo) {
        // 查询是否存在,存在直接返回
        LambdaQueryWrapper<MaMaterialMeasureSingle> lqw = new LambdaQueryWrapper<>();
        lqw.eq(bo.getGysId() != null, MaMaterialMeasureSingle::getGysId, bo.getGysId());
        lqw.eq(bo.getMeasureQhId() != null, MaMaterialMeasureSingle::getMeasureQhId, bo.getMeasureQhId());
        lqw.orderByAsc(MaMaterialMeasureSingle::getManifestCode);
        List<MaMaterialMeasureSingle> res = baseMapper.selectList(lqw);
        if (CollectionUtils.isNotEmpty(res)) {
            // 截止上期未计量数量
            res.forEach(item -> {
                item.setPreUnmeNum(handlePreUnmeNum(item));
            });
            // 更新
            baseMapper.updateBatchById(res);
            return res;
        }
        // 不存在则先添加再返回
        List<MaMaterialMeasureSingle> data = new ArrayList<>();
        // 根据供应商id,供货日期
        List<MaMaterialProgressDetailsVo> detailsList = progressDetailsMapper.progressDetails(bo);
        detailsList.forEach(item -> {
            MaMaterialMeasureSingle bean = BeanUtil.copyProperties(item, MaMaterialMeasureSingle.class);
            bean.setMeasureQhId(bo.getMeasureQhId());
            bean.setQh(bo.getQh());
            bean.setManifestId(item.getManifestId());
            bean.setNumber(item.getOnceSupplyNumber());
            bean.setSettlementPrice(item.getManifestPrice());
            bean.setMeNum(item.getOnceSupplyNumber());
            if (ObjectUtils.isNotEmpty(item.getOnceSupplyNumber()) && ObjectUtils.isNotEmpty(item.getManifestPrice())) {
                BigDecimal num = item.getOnceSupplyNumber();
                BigDecimal price = item.getManifestPrice();
                BigDecimal total = num.multiply(price).setScale(2);
                bean.setTotal(total);
                bean.setMeTotal(total);
            }
            // 截止上期未计量数量
            bean.setPreUnmeNum(handlePreUnmeNum(bean));
            data.add(bean);
        });
        baseMapper.insertBatch(data);
        return data;
    }

    // 查询上一期的 截止上期未计量数量
    public BigDecimal handlePreUnmeNum(MaMaterialMeasureSingle bean) {
        Integer qh = bean.getQh();
        Long manifestId = bean.getManifestId();
        Long gysId = bean.getGysId();

        MaMaterialMeasureQh qhBean = null;
        MaMaterialMeasureSingle lastMeasureBean = null;

        if (qh > 1) {
            // 根据期号查询上一期的期数id
            LambdaQueryWrapper<MaMaterialMeasureQh> lqw1 = Wrappers.lambdaQuery();
            lqw1.eq(gysId != null, MaMaterialMeasureQh::getGysId, gysId);
            lqw1.eq(qh != null, MaMaterialMeasureQh::getQh, (qh-1));
            qhBean = qhMapper.selectOne(lqw1);

            Long lastMeasureQhId = qhBean.getMeasureQhId(); // 上一期期数id

            // 根据上一期的期数id和材料清单id查询上一期信息
            LambdaQueryWrapper<MaMaterialMeasureSingle> lqw2 = Wrappers.lambdaQuery();
            lqw2.eq(gysId != null, MaMaterialMeasureSingle::getGysId, gysId);
            lqw2.eq(manifestId != null, MaMaterialMeasureSingle::getManifestId, manifestId);
            lqw2.eq(lastMeasureQhId != null, MaMaterialMeasureSingle::getMeasureQhId, lastMeasureQhId);
            lastMeasureBean = baseMapper.selectOne(lqw2);
        }

        if (qh > 2) {
            // 大于第二期,计算规则: 上一期数量-上一期计量数量+上期截止上期未计量数量
            BigDecimal lastNum = null;
            BigDecimal lastMeNum = null;
            BigDecimal lastPreUnmeNum = null;
            BigDecimal preUnmeNum = null;

            if (ObjectUtils.isNotEmpty(lastMeasureBean)) {
                lastNum = lastMeasureBean.getNumber();
                lastMeNum = lastMeasureBean.getMeNum();
                lastPreUnmeNum = lastMeasureBean.getPreUnmeNum();

            } else {
                lastPreUnmeNum = BigDecimal.ZERO;
            }

            if (ObjectUtils.isNotEmpty(lastNum) && ObjectUtils.isNotEmpty(lastMeNum) && ObjectUtils.isNotEmpty(lastPreUnmeNum)) {
                BigDecimal subtract = lastNum.subtract(lastMeNum);
                preUnmeNum = subtract.add(lastPreUnmeNum);
            } else {
                preUnmeNum = BigDecimal.ZERO;
            }
            bean.setPreUnmeNum(preUnmeNum);
            return preUnmeNum;
        }
        else if (qh == 2) {
            // 第二期: 计算规则: 第一期数量-第一期计量数量+第一期截止上期未计量数量
            BigDecimal lastNumber = lastMeasureBean.getNumber();
            BigDecimal lastMeNum = lastMeasureBean.getMeNum();
            BigDecimal lastPreNum = lastMeasureBean.getPreUnmeNum();
            BigDecimal preUnmeNnum = null;
            if (ObjectUtils.isNotEmpty(lastNumber) && ObjectUtils.isNotEmpty(lastMeNum) && ObjectUtils.isNotEmpty(lastPreNum)) {
                BigDecimal subtract = lastNumber.subtract(lastMeNum);
                preUnmeNnum = subtract.add(lastPreNum);
            } else {
                preUnmeNnum = BigDecimal.ZERO;
            }
            bean.setPreUnmeNum(preUnmeNnum);
            return preUnmeNnum;
        }
        else {
            // 第一期,计算规则: 返回 0
            return BigDecimal.ZERO;
        }

    }

}
